package maosy.oauth2.server.config

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer
import org.springframework.security.oauth2.provider.token.DefaultTokenServices
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices
import org.springframework.security.oauth2.provider.token.TokenStore
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore
import javax.servlet.http.HttpServletResponse

@Configuration
@EnableResourceServer
open class ResourceServerConfig : ResourceServerConfigurerAdapter() {

    @Autowired
    lateinit var redisConnectionFactory: RedisConnectionFactory


    @Bean
    open fun tokenService(): ResourceServerTokenServices {
        return DefaultTokenServices().apply {
            setTokenStore(RedisTokenStore(redisConnectionFactory))
            setSupportRefreshToken(true)
        }
    }

    override fun configure(http: HttpSecurity?) {
        http?.let {
            it.csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint { request, response, authException ->
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
                }
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and().httpBasic()
        }
    }

    override fun configure(resources: ResourceServerSecurityConfigurer?) {
        resources?.tokenServices(tokenService())
    }

}